#include <cstdlib>
#include <sys/select.h>
#include <unistd.h>
#include <cstring>
#include "header.h"


int main()
{
    int clientfd = socket(AF_INET , SOCK_STREAM , 0);
    ERROR_CHECK(clientfd , -1 , "socket");

    struct sockaddr_in serveraddr;
    memset(&serveraddr , 0 , sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(9090);
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int ret = connect(clientfd , (const struct sockaddr *)&serveraddr , 
                      sizeof(serveraddr));
    ERROR_CHECK(ret , -1 , "connect");

    printf("客户端已成功连接到服务端 \n");

    // 通过 select 监听 cliented 和标准输入
    fd_set readset;
    FD_ZERO(&readset);
    
    // 指定用户态接收缓冲区
    char buff[1024] = {0};

    while(1)
    {
        FD_ZERO(&readset);
        FD_SET(clientfd , &readset);
        FD_SET(STDIN_FILENO , &readset);

        // 等待就绪事件
        int nready = select(clientfd + 1 , &readset , NULL , NULL , NULL);
        printf("select 返回值：%d \n" , nready);

        if(FD_ISSET(STDIN_FILENO , &readset))
        {
            // 监听到了标准输入
            memset(buff , 0 , sizeof(buff)); // 防止有脏数据
            // 使用 read 接收数据时，会包含'\n'
            ret = read(STDIN_FILENO , buff , sizeof(buff));
            // 发送给服务器
            ret = send(clientfd , buff , strlen(buff) , 0);
        printf("客户端: %s \n客户端发送了 %d 字节数据\n", buff, ret);
        }

        if(FD_ISSET(clientfd , &readset))
        {
            // 服务端给客户端发数据
            memset(buff , 0 , sizeof(buff)); // 防止有脏数据
            ret = recv(clientfd , buff , sizeof(buff) , 0);
            
            if(ret == 0)
            {
                break;
            }

            printf("服务端：%s \n客户端接收了 %d 字节数据\n", buff , ret);
            
        }

    }

    // 断开连接
    close(clientfd);
    printf("客户端已断开连接！\n");

    return 0;
}
